/* We're using a cooking library that isn't dependent on jQuery.cookie library, just to reduce dependencies. */ /*! * JavaScript Cookie v2.1.3 * https://github.com/js-cookie/js-cookie * * Copyright 2006, 2015 Klaus Hartl & Fagner Brack * Released under the MIT license */ !function(a){var b=!1;if(!b){var c=window.Cookies,d=window.Cookies=a();d.noConflict=function(){return window.Cookies=c,d}}}(function(){function a(){for(var a=0,b={};a1){if(f=a({path:"/"},d.defaults,f),"number"==typeof f.expires){var h=new Date;h.setMilliseconds(h.getMilliseconds()+864e5*f.expires),f.expires=h}try{g=JSON.stringify(e),/^[\{\[]/.test(g)&&(e=g)}catch(a){}return e=c.write?c.write(e,b):encodeURIComponent(String(e)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),b=encodeURIComponent(String(b)),b=b.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),b=b.replace(/[\(\)]/g,escape),document.cookie=[b,"=",e,f.expires?"; expires="+f.expires.toUTCString():"",f.path?"; path="+f.path:"",f.domain?"; domain="+f.domain:"",f.secure?"; secure":""].join("")}b||(g={});for(var i=document.cookie?document.cookie.split("; "):[],j=/(%[0-9A-Z]{2})+/g,k=0;k -1 ? '&' : '?') + interactionParam); } }; /* Wrapper for the trackLink function */ window.FS.Tealium.trackInteraction = function(type, name, detail, $el, extraData){ if(FS.Tealium.needsQueryStringParam($el)){ var interactionParam = (type || '') + "|" + (name || '') + "|" + (detail || ''); FS.Tealium.applyInteractionQueryStringParam($el, interactionParam); }else{ var interactionPayload = {interaction_type: type, interaction_name: name, interaction_detail: detail}; if(extraData){ $.extend(interactionPayload, extraData); } window.FS.Tealium.trackLink('interaction', interactionPayload); } }; /* Automatically tracks interactions on the page if elements are tagged with specific values */ if(!window.stopTealiumAutoTracking && window.$){ var trackByDataAttributes = function(el){ var eventName = el.data('event-name'); if(eventName){ var uid = el.data('uid'); var data = el.data('link-data'); if(!data){ //iterate through each attribute and look for 'data-track' prefixed items $.each(el[0].attributes, function() { if(this.specified && this.name.indexOf('data-track-') === 0) { data = data || {}; data[this.name.substr(11)] = el.data(this.name.substr(5)); } }); } //special URL handling for interaction clicks on links that will result in the window reloading //in this case, stop the default behavior and just change the windows location to the a's href //but append the interaction query string if(eventName === 'interaction' && FS.Tealium.needsQueryStringParam(el)){ var interactionParam = (data['interaction_type'] || '') + "|" + (data['interaction_name'] || '') + "|" + (data['interaction_detail'] || ''); FS.Tealium.applyInteractionQueryStringParam(el, interactionParam); }else{ FS.Tealium.trackLink(eventName, data, uid); } } }; $('body').on('click', '.tealium-track', function(e){ trackByDataAttributes($(this), e); }); //check if there are any scroll tracking elements on the page var scrollTrackingElems = $('body').find('.tealium-track-scroll'); if(scrollTrackingElems.length){ var isScrolledIntoView = function(elem){ var docViewTop = $(window).scrollTop(); var docViewBottom = docViewTop + $(window).height(); var elemTop = $(elem).offset().top; var elemBottom = elemTop + $(elem).height(); //either the entire element is in view or must have scrolled at least 200 pixels in; return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)) || docViewBottom >= (elemTop + 200); }; //attach a listener to the page $(window).scroll(function(){ //check to see if each of the elements are in view scrollTrackingElems.each(function (i, element){ var $element = $(element); if(isScrolledIntoView($element) && !$element.data('tealium-scroll-tracked')){ //mark that it's been scrolled too $element.data('tealium-scroll-tracked', true); trackByDataAttributes($element); } }); }); } } /* Allow for a deferred invokation. Works similar to the Google Maps api. Will look for a global funtion called 'onTealiumLibraryLoaded' and invoke */ if(window.onTealiumLibraryLoaded){ window.onTealiumLibraryLoaded(); } /******************************************************************************/ /** youtube tracking **********************************************************/ /** * onYouTubePlayerReady * * The default callback when the JS API is enabled */ FS.Tealium.onYouTubePlayerReady = function(event, options){ var youTubePlayer = event.target; // List the various player states for easy use later var youTubePlayerStates = { unstarted: -1, finished: 0, playing: 1, paused: 2, buffering: 3, cued: 5 }; var youtubeId = youTubePlayer.getVideoUrl().split('v=')[1]; var ampersandPosition = youtubeId.indexOf('&'); if(ampersandPosition != -1) { youtubeId = youtubeId.substring(0, ampersandPosition); } var videoName = youTubePlayer.getVideoData().title || youtubeId; //var videoName = jQuery('li.asset-wrapper.selected div.caption-info h2.asset-name').html().replace(/^\s+|\s+$/g,'').toLowerCase(); var videoDuration = youTubePlayer.getDuration(); var getName = function(name){ return options && options.namePrefix ? options.namePrefix + name : name; }; // Create a new array element for the video var youTubePlayerCallback = { played: false, // Has the video started yet? completed: false, // Has the video finished playing? name: getName(videoName), // The name of the video duration: videoDuration, // Can't get until previousState: youTubePlayerStates.unstarted, // Previous state, defaults to unstarted previousTime: 0, // Previous time, defaults to 0 (not started) watchingTimer: false, milestones: { "25": Math.floor(videoDuration / 4), "50": Math.floor(videoDuration / 2), "75": Math.floor(videoDuration * .75) }, checkMilestones: function(){ //is the video playing? if(youTubePlayer.getPlayerState() === 1){ var currentTime = Math.floor(youTubePlayer.getCurrentTime()); var trackingData = youTubePlayerCallback.getDefaultTrackingData(); Object.entries(youTubePlayerCallback.milestones).forEach(function(value) { var key = value[0], value = value[1]; if(currentTime === value){ trackingData.video_milestone_ID = key; FS.Tealium.trackLink('video_milestone',trackingData); return false; } }); } }, getDefaultTrackingData: function(){ return { 'video_name':youTubePlayerCallback.name, 'video_length': youTubePlayerCallback.duration, 'video_player': 'youtube' } }, stateChange: function (newState) { // Grab the current state var currentState = youTubePlayer.getPlayerState(); // Get the current position to the nearest next second var currentTime = Math.ceil(youTubePlayer.getCurrentTime()); // Figure out what state we are in switch(currentState) { // Video has been initialized, but not started case youTubePlayerStates.unstarted: break; // Video finished case youTubePlayerStates.finished: // Show that we have indeed completed the video youTubePlayerCallback.completed = true; FS.Tealium.trackLink('video_complete',youTubePlayerCallback.getDefaultTrackingData()); clearInterval(youTubePlayerCallback.watchingTimer); break; // Video started to play case youTubePlayerStates.playing: // This video has never been played before if(!youTubePlayerCallback.played) { // Show that we have started to play the video youTubePlayerCallback.played = true; FS.Tealium.trackLink('video_start',youTubePlayerCallback.getDefaultTrackingData()); //start a timer to keep track of milestones youTubePlayerCallback.watchingTimer = setInterval(youTubePlayerCallback.checkMilestones, 1000); } else if(youTubePlayerCallback.played && youTubePlayerCallback.completed) { // The video has been played before, and has recently finished (replay) // Show that we haven't finished the video yet (since we just started watching it again) youTubePlayerCallback.completed = false; } else { // Video Unpaused/played from buffering //start a timer to keep track of milestones youTubePlayerCallback.watchingTimer = setInterval(youTubePlayerCallback.checkMilestones, 1000); } break; // Video has been paused case youTubePlayerStates.paused: clearInterval(youTubePlayerCallback.watchingTimer); break; // Video is now buffering case youTubePlayerStates.buffering: clearInterval(youTubePlayerCallback.watchingTimer); break; // Video is cued up from a playlist case youTubePlayerStates.cued: break; // new / unknown state default: break; } // Setup our previous youTubePlayerStates for the next call this.previousTime = currentTime; this.previousState = currentState; } }; // Add an event listener for changes in the player's state if (youTubePlayer.addEventListener) { youTubePlayer.addEventListener("onStateChange", youTubePlayerCallback.stateChange); } } /******************************************************************************/ /******************************************************************************/ /** vimeo tracking **********************************************************/ /** * on vimeo player ready * */ FS.Tealium.onVimeoPlayerReady = function(player, options){ var playerState = { playing: false, completed: false }; var getName = function(title){ return options && options.namePrefix ? options.namePrefix + title : title; }; player.on('play', function(){ if(!playerState.playing){ playerState.playing = true; player.getVideoTitle().then(function(title){ window.FS.Tealium.trackLink('video_start',{'video_name':getName(title)}); }); }else if(playerState.playing && playerState.completed){ playerState.completed = false; } }); player.on('ended', function(){ playerState.completed = true; player.getVideoTitle().then(function(title){ window.FS.Tealium.trackLink('video_complete',{'video_name':getName(title)}); }); }); };